import requestAnalysisRequestNumberApi from '@/api/request/requestAnalysisRequestNumberApi'
import requestRankingApi from '@/api/request/requestRankingApi'
import requestSlowRankingApi from '@/api/request/requestSlowRankingApi'
import serverInfoApi from '@/api/server/serverInfoApi'
import userAnalysisUserNumberApi from '@/api/user/userAnalysisUserNumberApi'
import IUserAnalysisUserNumberForm from '@/model/form/user/IUserAnalysisUserNumberForm'
import IRequestRankingVO from '@/model/vo/request/IRequestRankingVO'
import { toThousands } from '@/util/CommonUtil'
import { Avatar, Select, Spin, Tooltip } from '@douyinfe/semi-ui'
import * as echarts from 'echarts'
import { MutableRefObject, useEffect, useRef, useState } from 'react'

const userChartId = 'userChart' // 用户数
const requestChartId = 'requestChart' // 请求数
const serviceChartId = 'serviceChart' // 服务器状态

export default function Analysis() {
  const userChart = useRef<echarts.EChartsType>()
  const requestChart = useRef<echarts.EChartsType>()
  const serviceChart = useRef<echarts.EChartsType>()
  const [requestChartValue, setRequestChartValue] = useState(2) // 请求数的 type值
  const [requestRankingData, setRequestRankingData] =
    useState<IRequestRankingVO[]>() // 请求总数排行
  const [requestRankingLoading, setRequestRankingLoading] = useState(true) // 请求总数排行 loading
  const [requestSlowRankingData, setRequestSlowRankingData] =
    useState<IRequestRankingVO[]>() // 慢请求排行
  const [requestSlowRankingLoading, setRequestSlowRankingLoading] =
    useState(true) // 慢请求排行 loading

  useEffect(() => {
    if (userChart.current) {
      userChart.current.dispose()
    }
    if (requestChart.current) {
      requestChart.current.dispose()
    }
    if (serviceChart.current) {
      serviceChart.current.dispose()
    }
    userChart.current = echarts.init(document.getElementById(userChartId)!)
    requestChart.current = echarts.init(
      document.getElementById(requestChartId)!
    )
    serviceChart.current = echarts.init(
      document.getElementById(serviceChartId)!
    )

    setUserChartOption(userChart)
    userChart.current.on('legendselectchanged', (params: { name: any }) => {
      setUserChartOption(userChart, { type: Number(params.name) })
    })

    setRequestChartOption(requestChart, { type: requestChartValue })

    setRequestRankingLoading(true)
    requestRankingApi().then(({ data }) => {
      setRequestRankingLoading(false)
      setRequestRankingData(data.data)
    })

    setRequestSlowRankingLoading(true)
    requestSlowRankingApi().then(({ data }) => {
      setRequestSlowRankingLoading(false)
      setRequestSlowRankingData(data.data)
    })

    setServiceChartOption(serviceChart)
  }, [])

  const requestChartOptionList = [
    { value: 1, label: '最近一天' },
    { value: 2, label: '最近一月' },
    { value: 3, label: '最近一年' },
    { value: 4, label: '所有' },
  ]

  return (
    <div className="flex-c wh100 bg">
      <div className="flex1 flex-center wh100 m-t-20">
        <div
          id={userChartId}
          className="flex-center flex1 wh100 white-bg b-r-14 m-20"
        ></div>
        <div className="flex-c ai-c jc-c flex1 wh100 white-bg b-r-14 m-t-b-20 m-r-20">
          <div className="flex jc-e w100 ">
            <Select
              className="m-10"
              style={{ width: 180 }}
              optionList={requestChartOptionList}
              value={requestChartValue}
              onChange={(value) => {
                setRequestChartValue(Number(value))
                setRequestChartOption(requestChart, { type: Number(value) })
              }}
            ></Select>
          </div>
          <div id={requestChartId} className="flex1 wh100"></div>
        </div>
      </div>

      <div className="flex1 flex-center wh100 m-t-b-20">
        <div className="flex-c flex1 wh100 white-bg b-r-14 m-20">
          <div className="flex-center border-b p-10">请求总数排行</div>
          <Spin
            spinning={requestRankingLoading}
            wrapperClassName="overflow-y-flex w100 m-b-10"
          >
            {requestRankingData?.map((item, index) => {
              return (
                <div
                  className={`flex ai-c jc-sb m-t-10 ${
                    index <= 2 ? 'fw-600 f-18' : ''
                  }`}
                  key={index}
                >
                  <Tooltip content={item.name}>
                    <div className="flex ai-c">
                      <div className="w-50 flex jc-c">
                        <Avatar
                          className="cursor-def"
                          color={index <= 2 ? 'purple' : 'teal'}
                          size={index <= 2 ? 'small' : 'extra-extra-small'}
                        >
                          <span>{index + 1}</span>
                        </Avatar>
                      </div>
                      <span className="cursor-def">{item.uri}</span>
                    </div>
                  </Tooltip>
                  <Tooltip
                    content={'平均耗时：' + toThousands(item.avg) + ' ms'}
                  >
                    <span className="m-r-20 cursor-def">
                      {toThousands(item.count)}
                    </span>
                  </Tooltip>
                </div>
              )
            })}
          </Spin>
        </div>
        <div
          id={serviceChartId}
          style={{ maxHeight: '236px' }}
          className="flex-center flex1 wh100 white-bg b-r-14 m-t-b-20 m-r-20 p-t-b-10"
        ></div>
        <div className="flex-c flex1 wh100 white-bg b-r-14 m-20">
          <div className="flex-center border-b p-10">慢请求排行</div>
          <Spin
            spinning={requestSlowRankingLoading}
            wrapperClassName="overflow-y-flex w100 m-b-10"
          >
            {requestSlowRankingData?.map((item, index) => {
              return (
                <div
                  className={`flex ai-c jc-sb m-t-10 ${
                    index <= 2 ? 'fw-600 f-18' : ''
                  }`}
                  key={index}
                >
                  <Tooltip content={item.name}>
                    <div className="flex ai-c">
                      <div className="w-50 flex jc-c">
                        <Avatar
                          className="cursor-def"
                          color={index <= 2 ? 'red' : 'amber'}
                          size={index <= 2 ? 'small' : 'extra-extra-small'}
                        >
                          <span>{index + 1}</span>
                        </Avatar>
                      </div>
                      <span className="cursor-def">{item.uri}</span>
                    </div>
                  </Tooltip>
                  <Tooltip content={'请求次数：' + toThousands(item.count)}>
                    <span className="m-r-20 cursor-def">
                      {toThousands(item.avg)} ms
                    </span>
                  </Tooltip>
                </div>
              )
            })}
          </Spin>
        </div>
      </div>
    </div>
  )
}

// 设置用户数 chart的数据
function setUserChartOption(
  userChart: MutableRefObject<echarts.EChartsType | undefined>,
  form: IUserAnalysisUserNumberForm = { type: 2 }
) {
  userChart.current?.showLoading()
  userAnalysisUserNumberApi(form).then(({ data }) => {
    userChart.current?.hideLoading()
    const xData = data.data.map((item) => item.date)
    const yData = data.data.map((item) => item.count)
    userChart.current?.setOption({
      tooltip: {
        trigger: 'axis',
        formatter: (params, ticket, callback) => {
          if (params instanceof Array) {
            return `用户总数 <br /> ${params[0].marker} ${params[0].name}：<strong>${params[0].value}</strong>`
          }
          return ''
        },
      },
      legend: {
        icon: 'roundRect',
        selectedMode: 'single',
        selected: {
          '1': form.type === 1,
          '2': form.type === 2,
          '3': form.type === 3,
        },
        formatter: (name: string) => {
          switch (name) {
            case '1':
              return '最近一月'
            case '2':
              return '最近一年'
            case '3':
              return '所有'
            default:
              return name
          }
        },
      },
      xAxis: {
        data: xData,
      },
      yAxis: {
        name: '用户总数',
      },
      toolbox: {
        feature: {
          dataView: { readOnly: true },
          saveAsImage: {},
        },
      },
      series: [
        {
          smooth: true,
          areaStyle: {},
          symbol: 'none',
          name: '1',
          type: 'line',
          data: form.type === 1 ? yData : [],
          markLine: {
            data: [{ type: 'average' }],
          },
        },
        {
          smooth: true,
          areaStyle: {},
          symbol: 'none',
          name: '2',
          type: 'line',
          data: form.type === 2 ? yData : [],
          markLine: {
            data: [{ type: 'average' }],
          },
        },
        {
          smooth: true,
          areaStyle: {},
          symbol: 'none',
          name: '3',
          type: 'line',
          data: form.type === 3 ? yData : [],
          markLine: {
            data: [{ type: 'average' }],
          },
        },
      ],
    })
  })
}

// 设置请求数 chart的数据
function setRequestChartOption(
  requestChart: MutableRefObject<echarts.EChartsType | undefined>,
  form: IUserAnalysisUserNumberForm = { type: 1 }
) {
  requestChart.current?.showLoading()
  requestAnalysisRequestNumberApi(form).then(({ data }) => {
    requestChart.current?.hideLoading()
    let temp: Record<string, number> = {}
    const yData1: number[] = []
    const yData2: number[] = []
    const yData3: number[] = []
    data.data.forEach((item) => {
      if (temp[item.date]) {
        temp[item.date] = temp[item.date] + 1 // 设置总数
      } else {
        temp[item.date] = 1 // 设置总数
      }
    })

    const xData = Object.keys(temp)

    // 设置初始值
    xData.forEach(() => {
      yData1.push(0)
      yData2.push(0)
      yData3.push(0)
    })

    data.data.forEach((item) => {
      if (item.category === 1) {
        yData1[xData.indexOf(item.date)] = item.count
      } else if (item.category === 2) {
        yData2[xData.indexOf(item.date)] = item.count
      } else if (item.category === 3) {
        yData3[xData.indexOf(item.date)] = item.count
      }
    })

    requestChart.current?.setOption({
      tooltip: {
        trigger: 'axis',
        formatter: (params, ticket, callback) => {
          if (params instanceof Array) {
            let count = 0
            let resStr = ''
            params.forEach((item) => {
              resStr += `<br /> ${item.marker} ${item.seriesName}：<strong>${item.value}</strong>`
              count += Number(item.value)
            })
            return `${params[0].name}：<strong>${count}</strong>` + resStr
          }
          return ''
        },
      },
      legend: {},
      xAxis: {
        data: xData,
        type: 'category',
      },
      yAxis: {
        name: '请求总数',
      },
      toolbox: {
        feature: {
          dataView: { readOnly: true },
          magicType: { type: ['stack'] },
          saveAsImage: {},
        },
      },
      series: [
        {
          smooth: true,
          areaStyle: {},
          symbol: 'none',
          type: 'line',
          name: 'H5（网页端）',
          data: yData1,
          markLine: {
            data: [{ type: 'average' }],
          },
        },
        {
          smooth: true,
          areaStyle: {},
          symbol: 'none',
          type: 'line',
          name: 'APP（移动端）',
          data: yData2,
          markLine: {
            data: [{ type: 'average' }],
          },
        },
        {
          smooth: true,
          areaStyle: {},
          symbol: 'none',
          type: 'line',
          name: 'PC（桌面程序）',
          data: yData3,
          markLine: {
            data: [{ type: 'average' }],
          },
        },
      ],
    })
  })
}

// 设置服务器状态 chart的数据
function setServiceChartOption(
  serviceChart: MutableRefObject<echarts.EChartsType | undefined>
) {
  serviceChart.current?.showLoading()
  serverInfoApi().then(({ data }) => {
    serviceChart.current?.hideLoading()
    const memoryTotal = Number((data.data.memoryTotal / 1024 / 1024).toFixed(2))
    const sizeTotal = Number((data.data.sizeTotal / 1024 / 1024).toFixed(2))
    const jvmMaxMemory = Number(
      (data.data.jvmMaxMemory / 1024 / 1024).toFixed(2)
    )
    const memoryUsing = Number((data.data.memoryUsing / 1024 / 1024).toFixed(2))
    const writesTotal = Number((data.data.writesTotal / 1024 / 1024).toFixed(2))
    const jvmUsingMemory = Number(
      (data.data.jvmUsingMemory / 1024 / 1024).toFixed(2)
    )

    serviceChart.current?.setOption({
      tooltip: {
        formatter: (params, ticket, callback) => {
          if (!(params instanceof Array)) {
            let relVal = params.name + '使用率：'
            params.data.value.forEach((item: number, index: number) => {
              relVal += '<br/>' + params.marker
              if (index === 0) {
                relVal +=
                  ' 磁盘：' + ((item / sizeTotal) * 100).toFixed(2) + ' %'
              } else if (index === 1) {
                relVal += ' cpu ：' + item + ' %'
              } else if (index === 2) {
                relVal +=
                  ' jvm ：' + ((item / jvmMaxMemory) * 100).toFixed(2) + ' %'
              } else if (index === 3) {
                relVal +=
                  ' 内存：' + ((item / memoryTotal) * 100).toFixed(2) + ' %'
              }
            })
            return relVal
          }
          return ''
        },
      },
      radar: {
        shape: 'circle',
        indicator: [
          { name: `磁盘 ${sizeTotal}MB`, max: sizeTotal },
          { name: `cpu 100%`, max: 100 },
          { name: `jvm ${jvmMaxMemory}MB`, max: jvmMaxMemory },
          { name: `内存 ${memoryTotal}MB`, max: memoryTotal },
        ],
      },
      series: [
        {
          areaStyle: {},
          type: 'radar',
          data: [
            {
              value: [
                writesTotal,
                data.data.cpuUsing.toFixed(2),
                jvmUsingMemory,
                memoryUsing,
              ],
              name: '服务器',
            },
          ],
          // 在拐点处显示数值
          label: {
            show: true,
            formatter: (params: any) => {
              if (params.dimensionIndex === 1) {
                return params.value + ' %'
              }
              return params.value + ' MB'
            },
          },
        },
      ],
    })
  })
}
